#include "write.h"
#include "kstd.h"

static int g_x;
static int g_y;
static int g_color;

void init_console ()
{
  g_color = 7;
  clear ();
}

void set_color (int col)
{
  g_color = col;
}

void move_up ()
{
  char* frb = (void*) 0xb8000;
  int i;

  for (i = 0; i < 3840; ++i) //2 * 80 * 24 = 3840
    {
      frb[i] = frb[i + 160];
    }
  for (i = 0; i < 80 * 2; ++i)
    {
      frb[1 + (1920 + i) * 2] = 0; // 80 * 24 = 1920
      frb[(1920 + i) * 2] = 0; // 80 * 24 = 1920
    }
  g_y = 24;
}

int write (const char* s, size_t length)
{
  size_t i;
  size_t u;
  char* frb = (void*) 0xb8000;
  int escaped = 0;

  for (i = 0; i < length; i++)
    {
      if ((escaped == 0) && ((unsigned char)s[i] == CONS_ESCAPE))
	escaped = 1;
      else if (escaped)
	{
	  escaped = 0;
	  if ((unsigned char)s[i] == CONS_CLEAR)
	    clear ();
	  else if ((unsigned char)s[i] == CONS_COLOR)
	    {
	      if (++i < length)
		g_color = (unsigned char)s[i];
	    }
	  else if ((unsigned char)s[i] == CONS_SETX)
            {
              if (++i < length && (unsigned char)s[i] < 80)
                g_x = (unsigned char)s[i];
            }
	  else if ((unsigned char)s[i] == CONS_SETY)
            {
              if (++i < length && (unsigned char)s[i] < 25)
                g_y = (unsigned char)s[i];
            }
	}
      else if (s[i] == '\r')
	g_x = 0;
      else if (s[i] == '\n')
	{
	  g_x = 0;
	  if (++g_y >= 25)
	    move_up ();
	}
      else if (s[i] == '\t')
	{
	  for (u = 0; u < 8; u++)
	    {
	      if (g_y >= 25)
		move_up ();
	      frb[(g_y * 80 + g_x) * 2] = ' ';
	      frb[1 + (g_y * 80 + g_x) * 2] = g_color;
	      g_x++;
	      if (g_x >= 80)
		{
		  g_x = 0;
		  ++g_y;
		}
	    }
	}
      else
	{
	  if (g_y >= 25)
	    move_up ();
	  frb[(g_y * 80 + g_x) * 2] = s[i];
	  frb[1 + (g_y * 80 + g_x) * 2] = g_color;
	  g_x++;
	  if (g_x >= 80)
	    {
	      g_x = 0;
	      ++g_y;
	    }
	}
    }
  return length;
}

void clear ()
{
  char* frb = (void*) 0xb8000;
  int x;
  int y;

  g_x = 0;
  g_y = 0;
  for (y = 0; y < 25; y++)
    for (x = 0; x < 80; x++)
      {
	frb[1 + (80 * y + x) * 2] = 7;
	frb[(80 * y + x) * 2] = 0;
      }
}
